#ifndef __PACKET_BUILDER_H__
#define __PACKET_BUILDER_H__ 1

#include "packet_source.h"
#include "ext_bit_source.h"
#include "properties_reader.h"

#include <vector>

class CPacketBuilder : public IExtBitSource
{
public:

	CPacketBuilder(CPropertiesReader* pConfig, IPacketSource* pPacketSource);
	virtual ~CPacketBuilder();

	virtual EBitValue getBit();
	virtual void putBit(bool pBitValue, bool pFirstBit);
	virtual unsigned int getMaxFrameLength();

private:
	enum ESendPacketState
	{
		SEND_STATE_WAIT_FOR_NEXT = 0,
		SEND_STATE_NEXT_IS_READY,
		SEND_STATE_PACKET,
	};

	enum ERecvPacketState
	{
		RECV_STATE_WAIT_FOR_NEXT = 0,
		RECV_STATE_BEGIN,
		RECV_STATE_LENGTH_FIELD,
		RECV_STATE_PAYLOAD,
	};

	static const std::string sIniSection;

	bool mError;
	CPropertiesReader* mConfig;
	IPacketSource* mPacketSource;

	unsigned int mMaxPayload;
	bool mIgnoreWrongCRC;

	NPacketSource::EPayloadInfo mSendPayloadInfo;
	ESendPacketState mSendState;
	std::vector<bool> mSendPacket;
	unsigned int mSendBitCount;
	unsigned int mSendBitIndex;
	unsigned int mSendPayloadLength;

	ERecvPacketState mRecvState;
	std::vector<bool> mRecvPacket;
	unsigned int mRecvBitCount;
	unsigned int mRecvBitIndex;
	unsigned int mRecvPayloadLength;
#if 0
	unsigned char *mReadBuf; // is used for getBit payload
	unsigned int mReadBufLen; // full byte length of mReadBuf
	unsigned int mReadPayloadLen; // payload length of current frame
	unsigned int mReadIndex;
#endif
	NPacketSource::EPayloadInfo createNextSendPacket();
	//void setPayloadForSend(unsigned char* pPayload, unsigned int pLength);

	bool writeByteToBoolVector(std::vector<bool> &pVector,
			unsigned int pStartIndex,
			unsigned char pByteValue);

	bool readByteFromBoolVector(std::vector<bool> &pVector,
			unsigned int pStartIndex,
			unsigned char& pByteValue);

	unsigned int readBytesFromBoolVector(std::vector<bool> &pVector,
			unsigned int pStartIndex,
			void* pBytes,
			unsigned int pLength);

	CPacketBuilder(const CPacketBuilder& );
	CPacketBuilder& operator=(const CPacketBuilder& );
};

#endif // __PACKET_BUILDER_H__
